home *** CD-ROM | disk | FTP | other *** search
/ X User Tools / X User Tools (O'Reilly and Associates)(1994).ISO / sources / xman / misc.c < prev    next >
C/C++ Source or Header  |  1994-09-27  |  19KB  |  682 lines

  1. /*
  2.  * xman - X window system manual page display program.
  3.  *
  4.  * $XConsortium: misc.c,v 1.29 91/09/03 18:21:49 dave Exp $
  5.  *
  6.  * Copyright 1987, 1988 Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that the above copyright notice appear in all copies and that both that
  11.  * copyright notice and this permission notice appear in supporting
  12.  * documentation, and that the name of M.I.T. not be used in advertising or
  13.  * publicity pertaining to distribution of the software without specific,
  14.  * written prior permission.  M.I.T. makes no representations about the
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * Author:    Chris D. Peterson, MIT Project Athena
  19.  * Created:   October 27, 1987
  20.  */
  21.  
  22. #include "globals.h"
  23. #include "vendor.h"
  24. #include <X11/Xos.h>         /* sys/types.h and unistd.h included in here */
  25. #include <sys/stat.h>
  26. #include <errno.h>
  27. #include <X11/Xaw/Dialog.h>
  28. #include <X11/Shell.h>
  29.  
  30. static FILE * Uncompress();
  31. static Boolean UncompressNamed(), UncompressUnformatted();
  32. extern int errno;        /* error codes. */
  33.  
  34. /*    Function Name: PopupWarning
  35.  *    Description: This function pops upa warning message.
  36.  *    Arguments: string - the specific warning string.
  37.  *    Returns: none
  38.  */
  39.  
  40. extern Widget initial_widget, top;
  41. static Widget warnShell, warnDialog;
  42.  
  43. void 
  44. PopdownWarning(w, client, call)
  45.      Widget w; XtPointer client, call;
  46. {
  47.   XtPopdown((Widget)client);
  48. }
  49.  
  50. void
  51. PopupWarning(man_globals, string)
  52. ManpageGlobals * man_globals;
  53. char * string;
  54. {
  55.   int n;
  56.   Arg wargs[3];
  57.   Dimension topX, topY;
  58.   char buffer[BUFSIZ];
  59.   Widget positionto;
  60.   Boolean hasPosition;
  61.  
  62.   sprintf( buffer, "Xman Warning: %s", string);
  63.   hasPosition = FALSE;
  64.   if (man_globals->This_Manpage)
  65.     positionto = man_globals->This_Manpage;
  66.   else
  67.     positionto = top;
  68.   if (top)
  69.   {
  70.     n=0;
  71.     XtSetArg(wargs[n], XtNx, &topX); n++;
  72.     XtSetArg(wargs[n], XtNy, &topY); n++;
  73.     XtGetValues(top, wargs, n);
  74.     hasPosition = TRUE;
  75.   }
  76.  
  77.   if (man_globals != NULL) 
  78.     ChangeLabel(man_globals->label, buffer);
  79.   if (man_globals->label == NULL) {
  80.     n=0;
  81.     if (hasPosition)
  82.     {
  83.       XtSetArg(wargs[n], XtNx, topX); n++;
  84.       XtSetArg(wargs[n], XtNy, topY); n++;
  85.     }
  86.     XtSetArg(wargs[n], XtNtransientFor, top); n++;
  87.     warnShell = XtCreatePopupShell("warnShell", transientShellWidgetClass, 
  88.                    initial_widget, wargs, n);
  89.     XtSetArg(wargs[0], XtNlabel, buffer); 
  90.     warnDialog = XtCreateManagedWidget("warnDialog", dialogWidgetClass, 
  91.                        warnShell, wargs, 1);
  92.     XawDialogAddButton(warnDialog, "dismiss", PopdownWarning, 
  93.                (XtPointer)warnShell);
  94.     XtRealizeWidget(warnShell);
  95.     Popup(warnShell, XtGrabNone);
  96.   }
  97. }
  98.  
  99.  
  100. /*      THIS ROUTINE IS OBSOLETE...
  101.  *    Function Name: PrintWarning
  102.  *    Description: This function prints a warning message to stderr.
  103.  *    Arguments: string - the specific warning string.
  104.  *    Returns: none
  105.  */
  106.  
  107. void
  108. PrintWarning(man_globals, string)
  109. ManpageGlobals * man_globals;
  110. char * string;
  111. {
  112.   char buffer[BUFSIZ];
  113.  
  114.   sprintf( buffer, "Xman Warning: %s", string);
  115.  
  116.   if (man_globals != NULL) 
  117.     ChangeLabel(man_globals->label, buffer);
  118.  
  119.   fprintf(stderr, "%s\n", buffer);
  120. }
  121.  
  122. /*    Function Name: PrintError
  123.  *    Description: This Function prints an error message and exits.
  124.  *    Arguments: string - the specific message.
  125.  *    Returns: none. - exits tho.
  126.  */
  127.  
  128. void
  129. PrintError(string)
  130. char * string;
  131. {
  132.   fprintf(stderr,"Xman Error: %s\n",string);
  133.   exit(1);
  134. }
  135.  
  136. /*    Function Name: OpenFile
  137.  *    Description: Assignes a file to the manpage.
  138.  *    Arguments: man_globals - global structure.
  139.  *                 file        - the file pointer.
  140.  *    Returns: none
  141.  */
  142.  
  143. void
  144. OpenFile(man_globals, file)
  145. ManpageGlobals * man_globals;
  146. FILE * file;
  147. {
  148.   Arg arglist[1];
  149.   Cardinal num_args = 0;
  150.  
  151.   XtSetArg(arglist[num_args], XtNfile, file); num_args++;
  152.   XtSetValues(man_globals->manpagewidgets.manpage, arglist, num_args);
  153. }
  154.  
  155.  
  156. /*    Function Name: FindManualFile
  157.  *    Description: Opens the manual page file given the entry information.
  158.  *    Arguments: man_globals - the globals info for this manpage.
  159.  *                 section_num - section number of the man page.
  160.  *                 entry_num   - entry number of the man page.
  161.  *    Returns: fp - the file pointer
  162.  *
  163.  * NOTES:
  164.  *
  165.  * If there is a uncompressed section it will look there for uncompresed 
  166.  * manual pages first and then for individually comressed file in the 
  167.  * uncompressed section.
  168.  * 
  169.  * If there is a compressed directory then it will also look there for 
  170.  * the manual pages.
  171.  *
  172.  * If both of these fail then it will attempt to format the manual page.
  173.  */
  174.  
  175. FILE *
  176. FindManualFile(man_globals, section_num, entry_num)
  177. ManpageGlobals * man_globals;
  178. int section_num, entry_num;
  179. {
  180.   FILE * file;
  181.   char path[BUFSIZ], page[BUFSIZ], section[BUFSIZ], *temp;
  182.   char filename[BUFSIZ];
  183.   char * entry = manual[section_num].entries[entry_num];
  184.   int len_cat = strlen(CAT);
  185.  
  186.   temp = CreateManpageName(entry);
  187.   sprintf(man_globals->manpage_title, "The current manual page is: %s.", temp);
  188.   XtFree(temp);
  189.   
  190.   ParseEntry(entry, path, section, page);
  191.  
  192. /*
  193.  * Look for uncompressed files first.
  194.  */
  195.  
  196.   sprintf(filename, "%s/%s%s/%s", path, CAT, section + len_cat, page);
  197.   if ( (file = fopen(filename,"r")) != NULL)
  198.     return(file);
  199.  
  200. /*
  201.  * Then for compressed files in an uncompressed directory.
  202.  */
  203.  
  204.   sprintf(filename, "%s/%s%s/%s.%s", path, CAT, 
  205.       section + len_cat, page, COMPRESSION_EXTENSION);
  206.   if ( (file = Uncompress(man_globals, filename)) != NULL) 
  207.     return(file);
  208.  
  209. /*
  210.  * And lastly files in a compressed directory.
  211.  *
  212.  * The directory is not actually compressed it is just named man#.Z
  213.  * and all files in it are compressed without the .Z extension.
  214.  * HP does it this way (really :-).
  215.  */
  216.  
  217.   sprintf(filename, "%s/%s%s.%s/%s", path, CAT, section + len_cat,
  218.       COMPRESSION_EXTENSION, page);
  219.   if ( (file = Uncompress(man_globals, filename)) != NULL)
  220.     return(file);
  221. /*
  222.  * We did not find any preformatted manual pages, try to format it.
  223.  */
  224.  
  225.   return(Format(man_globals, entry));
  226. }
  227.  
  228. /*    Function Namecompress
  229.  *    Description: This function will attempt to find a compressed man
  230.  *                   page and uncompress it.
  231.  *    Arguments: man_globals - the psuedo global info.
  232.  *                 filename - name of file to uncompress.
  233.  *    Returns:; a pointer to the file or NULL.
  234.  */
  235.  
  236. static FILE *
  237. Uncompress(man_globals, filename)
  238. ManpageGlobals * man_globals;
  239. char * filename;
  240. {
  241.   char tmpfile[BUFSIZ], error_buf[BUFSIZ];
  242.   FILE * file;
  243.  
  244.   if ( !UncompressNamed(man_globals, filename, tmpfile) )
  245.     return(NULL);
  246.  
  247.   else if ((file = fopen(tmpfile, "r")) == NULL) {  
  248.     sprintf(error_buf, "Something went wrong in retrieving the %s",
  249.         "uncompressed manual page try cleaning up /tmp.");
  250.     PopupWarning(man_globals, error_buf);
  251.   }
  252.  
  253.   unlink(tmpfile);        /* remove name in tree, it will remain
  254.                    until we close the fd, however. */
  255.   return(file);
  256. }
  257.  
  258. /*    Function Name: UncompressNamed
  259.  *    Description: This function will attempt to find a compressed man
  260.  *                   page and uncompress it.
  261.  *    Arguments: man_globals - the psuedo global info.
  262.  *                 filename - name of file to uncompress.
  263.  * RETURNED        output - the file name output (must be an allocated string).
  264.  *    Returns:; TRUE if the file was found.
  265.  */
  266.  
  267. static Boolean
  268. UncompressNamed(man_globals, filename, output)
  269. ManpageGlobals * man_globals;
  270. char * filename, * output;
  271. {
  272.   char tmp[BUFSIZ], cmdbuf[BUFSIZ], error_buf[BUFSIZ];
  273.   struct stat junk;
  274.  
  275.   if (stat(filename, &junk) != 0) { /* Check for existance of the file. */
  276.     if (errno != ENOENT) {
  277.       sprintf(error_buf, "Error while stating file %s, errno = %d",
  278.           filename, errno);
  279.       PopupWarning(man_globals, error_buf);
  280.     }
  281.     return(FALSE);
  282.   }
  283.  
  284. /*
  285.  * Using stdin is necessary to fool zcat since we cannot guarentee
  286.  * the .Z extension.
  287.  */
  288.  
  289.   strcpy(tmp, MANTEMP);        /* get a temp file. */
  290.   (void) mktemp(tmp);
  291.   strcpy(output, tmp);
  292.  
  293.   sprintf(cmdbuf, UNCOMPRESS_FORMAT, filename, output);
  294.   if(system(cmdbuf) == 0)     /* execute search. */
  295.     return(TRUE);
  296.  
  297.   sprintf(error_buf, "Error while uncompressing, command was: %s", cmdbuf);
  298.   PopupWarning(man_globals, error_buf);
  299.   return(FALSE);
  300. }
  301.  
  302. /*    Function Name: Format
  303.  *    Description: This funtion formats the manual pages and interfaces
  304.  *                   with the user.
  305.  *    Arguments: man_globals - the psuedo globals
  306.  *                 file - the file pointer to use and return
  307.  *                 entry - the current entry struct.
  308.  *                 current_box - The current directory being displayed. 
  309.  *    Returns: none.
  310.  */
  311.  
  312. /* ARGSUSED */
  313.  
  314. FILE *
  315. Format(man_globals, entry)
  316. ManpageGlobals * man_globals; 
  317. char * entry;
  318. {
  319.   FILE * file;
  320.   Widget manpage = man_globals->manpagewidgets.manpage;
  321.   char cmdbuf[BUFSIZ], tmp[BUFSIZ], filename[BUFSIZ], error_buf[BUFSIZ];
  322.   char path[BUFSIZ];
  323.   XEvent event;
  324.   Position x,y;            /* location to pop up the
  325.                    "would you like to save" widget. */
  326.  
  327.   Popup(XtParent(man_globals->standby), XtGrabExclusive);
  328.   while ( !XCheckTypedWindowEvent(XtDisplay(man_globals->standby), 
  329.                   XtWindow(man_globals->standby), 
  330.                   Expose, &event) );
  331.   XtDispatchEvent( &event );
  332.   XFlush(XtDisplay(man_globals->standby));
  333.  
  334.   if ( !UncompressUnformatted(man_globals, entry, filename) ) {
  335.     /* We Really could not find it, this should never happen, yea right. */
  336.     sprintf(error_buf, "Could not open manual page, %s", entry);
  337.     PopupWarning(man_globals, error_buf);
  338.     XtPopdown( XtParent(man_globals->standby) );
  339.     return(NULL);
  340.   }
  341.  
  342.   strcpy(tmp,MANTEMP);                  /* Get a temp file. */
  343.   (void) mktemp(tmp);
  344.   strcpy(man_globals->tmpfile, tmp);
  345.   ParseEntry(entry, path, NULL, NULL);
  346.  
  347.   sprintf(cmdbuf,"cd %s ; %s %s %s > %s %s", path, TBL,
  348.       filename, FORMAT, man_globals->tmpfile, "2> /dev/null");
  349.  
  350.   if(system(cmdbuf) != 0) {    /* execute search. */
  351.     sprintf(error_buf,
  352.         "Something went wrong trying to run the command: %s", cmdbuf);
  353.     PopupWarning(man_globals, error_buf);
  354.     file = NULL;
  355.   }
  356.   else {
  357.     if ((file = fopen(man_globals->tmpfile,"r")) == NULL) {  
  358.       sprintf(error_buf, "Something went wrong in retrieving the %s",
  359.           "temp file, try cleaning up /tmp");
  360.       PopupWarning(man_globals, error_buf);
  361.     }
  362.     else {
  363.  
  364.       XtPopdown( XtParent(man_globals->standby) );
  365.   
  366.       if ( (man_globals->save == NULL) ||
  367.        (man_globals->manpagewidgets.manpage == NULL) ) 
  368.     unlink(man_globals->tmpfile);
  369.       else {
  370.     char * ptr, catdir[BUFSIZ];
  371.  
  372.     /*
  373.      * If the catdir is writeable then ask the user if he/she wants to
  374.      * write the man page to it. 
  375.      */
  376.  
  377.     strcpy(catdir, man_globals->save_file);
  378.     if ( (ptr = rindex(catdir, '/')) != NULL) {
  379.       *ptr = '\0';
  380.  
  381.       if ( access(catdir, W_OK) != 0 )
  382.         unlink(man_globals->tmpfile);
  383.       else {
  384.         x = (Position) Width(man_globals->manpagewidgets.manpage)/2;
  385.         y = (Position) Height(man_globals->manpagewidgets.manpage)/2;
  386.         XtTranslateCoords(manpage, x, y, &x, &y);
  387.         PositionCenter( man_globals->save, (int) x, (int) y, 0, 0, 0, 0);
  388.         XtPopup( man_globals->save, XtGrabExclusive);
  389.       }
  390.     }
  391.     else 
  392.       unlink(man_globals->tmpfile);
  393.       }
  394.     }
  395.   }
  396.  
  397.   if (man_globals->compress)    /* If the original was compressed
  398.                    then this is a tempory file. */
  399.     unlink(filename);
  400.   
  401.   return(file);
  402. }
  403.  
  404. /*    Function Name: UncompressUnformatted
  405.  *    Description: Finds an uncompressed unformatted manual page.
  406.  *    Arguments: man_globals - the psuedo global structure.
  407.  *                 entry - the manual page entry.
  408.  * RETURNED        filename - location to put the name of the file.
  409.  *    Returns: TRUE if the file was found.
  410.  */
  411.  
  412. static Boolean
  413. UncompressUnformatted(man_globals, entry, filename)
  414. ManpageGlobals * man_globals;
  415. char * entry, * filename;
  416. {
  417.   char path[BUFSIZ], page[BUFSIZ], section[BUFSIZ], input[BUFSIZ];
  418.   int len_cat = strlen(CAT), len_man = strlen(MAN);
  419.  
  420.   ParseEntry(entry, path, section, page);
  421.  
  422. /*
  423.  * Look for uncompressed file first.
  424.  */
  425.  
  426.   sprintf(filename, "%s/%s%s/%s", path, MAN, section + len_man, page);
  427.   if ( access( filename, R_OK ) == 0 ) {
  428.     man_globals->compress = FALSE;
  429.     sprintf(man_globals->save_file, "%s/%s%s/%s", path,
  430.         CAT, section + len_cat, page);
  431.     return(TRUE);
  432.   }
  433.  
  434. /*
  435.  * Then for compressed files in an uncompressed directory.
  436.  */
  437.  
  438.   sprintf(input, "%s.%s", filename, COMPRESSION_EXTENSION);
  439.   if ( UncompressNamed(man_globals, input, filename) ) {
  440.     man_globals->compress = TRUE;
  441.     sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path,
  442.         CAT, section + len_cat, page, COMPRESSION_EXTENSION);
  443.     return(TRUE);
  444.   }
  445. /*
  446.  * And lastly files in a compressed directory.
  447.  */
  448.  
  449.   sprintf(input, "%s/%s%s.%s/%s", path, 
  450.       MAN, section + len_man, COMPRESSION_EXTENSION, page);
  451.   if ( UncompressNamed(man_globals, input, filename) ) {
  452.     man_globals->compress = TRUE;
  453.     sprintf(man_globals->save_file, "%s/%s%s.%s/%s", path, 
  454.         CAT, section + len_cat, COMPRESSION_EXTENSION, page);
  455.     return(TRUE);
  456.   }
  457.   return(FALSE);
  458. }
  459.   
  460. /*    Function Name: AddCursor
  461.  *    Description: This function adds the cursor to the window.
  462.  *    Arguments: w - the widget to add the cursor to.
  463.  *                 cursor - the cursor to add to this widget.
  464.  *    Returns: none
  465.  */
  466.  
  467. void
  468. AddCursor(w,cursor)
  469. Widget w;
  470. Cursor cursor;
  471. {
  472.   XColor colors[2];
  473.   Arg args[10];
  474.   Cardinal num_args = 0;
  475.   Colormap c_map;
  476.   
  477.   if (!XtIsRealized(w)) {
  478.     PopupWarning(NULL, "Widget is not realized, no cursor added.\n");
  479.     return;
  480.   }
  481.  
  482.   XtSetArg( args[num_args], XtNcolormap, &c_map); num_args++;
  483.   XtGetValues( w, args, num_args);
  484.  
  485.   colors[0].pixel = resources.cursors.fg_color;
  486.   colors[1].pixel = resources.cursors.bg_color;
  487.  
  488.   XQueryColors (XtDisplay(w), c_map, colors, 2);
  489.   XRecolorCursor(XtDisplay(w), cursor, colors, colors+1);
  490.   XDefineCursor(XtDisplay(w),XtWindow(w),cursor);
  491. }
  492.  
  493. /*    Function Name: ChangeLabel
  494.  *    Description: This function changes the label field of the
  495.  *                   given widget to the string in str.
  496.  *    Arguments: w - the widget.
  497.  *                 str - the string to change the label to.
  498.  *    Returns: none
  499.  */
  500.  
  501. void
  502. ChangeLabel(w,str)
  503. Widget w;
  504. char * str;
  505. {
  506.   Arg arglist[3];        /* An argument list. */
  507.  
  508.   if (w == NULL) return;
  509.  
  510.   XtSetArg(arglist[0], XtNlabel, str);
  511.  
  512. /* shouldn't really have to do this. */
  513.   XtSetArg(arglist[1], XtNwidth, 0);
  514.   XtSetArg(arglist[2], XtNheight, 0);
  515.  
  516.   XtSetValues(w, arglist, (Cardinal) 1);
  517. }
  518.  
  519. /*
  520.  * In an ideal world this would be part of the XToolkit, and I would not
  521.  * have to do it, but such is life sometimes.  Perhaps in X11R3.
  522.  */
  523.  
  524. /*    Function Name: PositionCenter
  525.  *    Description: This fuction positions the given widgets center
  526.  *                   in the following location.
  527.  *    Arguments: widget - the widget widget to postion
  528.  *                 x,y - The location for the center of the widget
  529.  *                 above - number of pixels above center to locate this widget
  530.  *                 left - number of pixels left of center to locate this widget
  531.  *                 h_space, v_space - how close to get to the edges of the
  532.  *                                    parent window.
  533.  *    Returns: none
  534.  *      Note:  This should only be used with a popup widget that has override
  535.  *             redirect set.
  536.  */
  537.  
  538. void
  539. PositionCenter(widget,x,y,above,left,v_space,h_space)
  540. Widget widget;
  541. int x,y,above,left;
  542. int h_space,v_space;
  543. {
  544.   Arg wargs[2];
  545.   int x_temp,y_temp;        /* location of the new window. */
  546.   int parent_height,parent_width; /* Height and width of the parent widget or
  547.                    the root window if it has no parent. */
  548.  
  549.   x_temp = x - left - Width(widget) / 2 + BorderWidth(widget);
  550.   y_temp = y - above -  Height(widget) / 2 + BorderWidth(widget);
  551.  
  552.   parent_height = HeightOfScreen(XtScreen(widget));
  553.   parent_width = WidthOfScreen(XtScreen(widget));
  554.  
  555. /*
  556.  * Check to make sure that all edges are within the viewable part of the
  557.  * root window, and if not then force them to be.
  558.  */
  559.  
  560.   if (x_temp < h_space) 
  561.     x_temp = v_space;
  562.   if (y_temp < v_space)
  563.     (y_temp = 2);
  564.  
  565.   if ( y_temp + Height(widget) + v_space > parent_height )
  566.       y_temp = parent_height - Height(widget) - v_space; 
  567.  
  568.   if ( x_temp + Width(widget) + h_space > parent_width )
  569.       x_temp = parent_width - Width(widget) - h_space; 
  570.  
  571.   XtSetArg(wargs[0], XtNx, x_temp); 
  572.   XtSetArg(wargs[1], XtNy, y_temp); 
  573.   XtSetValues(widget, wargs, 2);
  574. }  
  575.  
  576. /*    Function Name: ParseEntry(entry, path, sect, page)
  577.  *    Description: Parses the manual pages entry filenames.
  578.  *    Arguments: str - the full path name.
  579.  *                 path - the path name.      RETURNED
  580.  *                 sect - the section name.   RETURNED
  581.  *                 page - the page name.      RETURNED
  582.  *    Returns: none.
  583.  */
  584.  
  585. void
  586. ParseEntry(entry, path, sect, page)
  587. char *entry, *path, *page, *sect;
  588. {
  589.   char *c, temp[BUFSIZ];
  590.  
  591.   strcpy(temp, entry);
  592.  
  593.   c = rindex(temp, '/');
  594.   if (c == NULL) 
  595.     PrintError("index failure in ParseEntry.");
  596.   *c++ = '\0';
  597.   if (page != NULL)
  598.     strcpy(page, c);
  599.  
  600.   c = rindex(temp, '/');
  601.   if (c == NULL) 
  602.     PrintError("index failure in ParseEntry.");
  603.   *c++ = '\0';
  604.   if (sect != NULL)
  605.     strcpy(sect, c);
  606.  
  607.   if (path != NULL)
  608.     strcpy(path, temp);
  609. }
  610.  
  611. /*      Function Name: GetGlobals
  612.  *      Description: Gets the psuedo globals associated with the
  613.  *                   manpage associated with this widget.
  614.  *      Arguments: w - a widget in the manpage.
  615.  *      Returns: the psuedo globals.
  616.  *      Notes: initial_widget is a globals variable.
  617.  *             manglobals_context is a global variable.
  618.  */
  619.  
  620. ManpageGlobals *
  621. GetGlobals(w)
  622. Widget w;
  623. {
  624.   Widget temp;
  625.   caddr_t data;
  626.  
  627.   while ( (temp = XtParent(w)) != initial_widget && (temp != NULL))
  628.     w = temp;
  629.  
  630.   if (temp == NULL) 
  631.     XtAppError(XtWidgetToApplicationContext(w), 
  632.            "Xman: Could not locate widget in tree, exiting");
  633.  
  634.   if (XFindContext(XtDisplay(w), XtWindow(w),
  635.            manglobals_context, &data) != XCSUCCESS)
  636.     XtAppError(XtWidgetToApplicationContext(w), 
  637.            "Xman: Could not find global data, exiting");
  638.  
  639.   return( (ManpageGlobals *) data);
  640. }
  641.   
  642. /*      Function Name: SaveGlobals
  643.  *      Description: Saves the psuedo globals on the widget passed
  644.  *                   to this function, although GetGlobals assumes that
  645.  *                   the data is associated with the popup child of topBox.
  646.  *      Arguments: w - the widget to associate the data with.
  647.  *                 globals - data to associate with this widget.
  648.  *      Returns: none.
  649.  *      Notes: WIDGET MUST BE REALIZED.
  650.  *             manglobals_context is a global variable.
  651.  */
  652.  
  653. void
  654. SaveGlobals(w, globals)
  655. Widget w;
  656. ManpageGlobals * globals;
  657. {
  658.   if (XSaveContext(XtDisplay(w), XtWindow(w), manglobals_context,
  659.            (caddr_t) globals) != XCSUCCESS)
  660.     XtAppError(XtWidgetToApplicationContext(w), 
  661.            "Xman: Could not save global data, are you out of memory?");
  662. }
  663.  
  664. /*      Function Name: RemoveGlobals
  665.  *      Description: Removes the psuedo globals from the widget passed
  666.  *                   to this function.
  667.  *      Arguments: w - the widget to remove the data from.
  668.  *      Returns: none.
  669.  *      Notes: WIDGET MUST BE REALIZED.
  670.  *             manglobals_context is a global variable.
  671.  */
  672.  
  673. void
  674. RemoveGlobals(w)
  675. Widget w;
  676. {
  677.   if (XDeleteContext(XtDisplay(w), XtWindow(w), 
  678.              manglobals_context) != XCSUCCESS)
  679.     XtAppError(XtWidgetToApplicationContext(w), 
  680.            "Xman: Could not remove global data?");
  681. }
  682.